package 极客算法训练营.chapter03;

/**
 * 给定一个链表，返回链表开始入环的第一个节点。 如果链表无环，则返回 null。
 * <p>
 * 为了表示给定链表中的环，我们使用整数 pos 来表示链表尾连接到链表中的位置（索引从 0 开始）。
 * 如果 pos 是 -1，则在该链表中没有环。注意，pos 仅仅是用于标识环的情况，并不会作为参数传递到函数中。
 * <p>
 * 说明：不允许修改给定的链表。
 */
public class 环形链表2 {
    public static class ListNode {
        int val;
        ListNode next;

        ListNode() {
        }

        ListNode(int val) {
            this.val = val;
        }

        ListNode(int val, ListNode next) {
            this.val = val;
            this.next = next;
        }
    }

    public static void main(String[] args) {

    }

    public ListNode detectCycle(ListNode head) {
        //边界条件，无环
        if (head == null || head.next == null) {
            return null;
        }
        ListNode slow = head, fast = head;
        //快慢指针判断是否有环,这里如果直接while-do不满足循环条件
        do {
            if (fast == null || fast.next == null) {
                return null;
            }
            fast = fast.next.next;
            slow = slow.next;
        } while (slow != fast);
        //循环结束，说明slow与fast已经相遇，将慢指针指向链表头
        slow = head;
        //两个指针同速移动，直至相遇
        while (slow != fast) {
            slow = slow.next;
            fast = fast.next;
        }
        //相遇点即为环入口
        return slow;
    }
}
